/**
 *   @file ThreadPool.h
 */
#ifndef _THREADPOOL_H_
#define _THREADPOOL_H_

#include "../common/BaseObject.h"
#include "../util/FuncPtrT.h"
#include "../collections/ArrayT.h"

namespace cppflib
{

namespace threading
{

class SyncLock;
class Semaphore;
class ThreadMemberInfo;

/**
 *  A thread pool to manage a number of idle and busy threads
 */
class _DLLAPI ThreadPool : public BaseObject
{
private:
    u32_t numThreads;
    collections::ArrayCppObjT<ThreadMemberInfo> * pBusyList;
    collections::ArrayCppObjT<ThreadMemberInfo> * pIdleList;
    volatile u32_t numIdleThreads;
    volatile u32_t numBusyThreads;
    SyncLock *pListLock;
    Semaphore *pIdleSem;

private:
    ThreadPool(void);

    ThreadMemberInfo *GetIdleMember();
    void ReturnToIdleList(ThreadMemberInfo *pMemberInfo);

public:
    //! custom function to be executed on an idle thread
    typedef util::FuncPtr1T<void, ptrany_t> UserFunc;

    explicit ThreadPool(u32_t numThreads);
    virtual ~ThreadPool(void);

    u32_t GetNumThreads();
    u32_t GetNumIdleThreads();
    u32_t GetNumBusyThreads();
    void StartAllThreads();
    void StopAllThreads();

    void ExecuteOnIdleThread(UserFunc *pUserFunc, ptrany_t pUserFuncArg);
};


} // end of namespace threading


} // end of namespace cppflib


#endif
